﻿using AutoMapper;
using MediatR;
using SmartCity.BasicData.Api.Write.Application.Command.GridType;
using SmartCity.BasicData.Common;
using SmartCity.BasicData.Common.Menus;
using SmartCity.BasicData.Domain;
using SmartCity.BasicData.Repo;
using System.Transactions;
using Yitter.IdGenerator;

namespace SmartCity.BasicData.Api.Write.Application.Handler.GridType
{
    /// <summary>
    /// 新建网格类型中介者处理器
    /// </summary>
    public class CreateGridTypeHandler : IRequestHandler<CreateGridTypeCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<GridTypeModel> gridTypeRepo;
        private readonly IBaseRepository<GridTypeProfessionMappingModel> gpRepo;//网格类型和专业映射表的仓储
        private readonly IMapper mapper;
        private readonly ILogger<CreateGridTypeHandler> logger;

        /// <summary>
        /// 通过构造函数的方式注册 仓储 mappper  日志组件
        /// </summary>
        /// <param name="gridTypeRepo"></param>
        /// <param name="mapper"></param>
        /// <param name="logger"></param>
        public CreateGridTypeHandler(IBaseRepository<GridTypeModel> gridTypeRepo,
            IBaseRepository<GridTypeProfessionMappingModel> gpRepo,
            IMapper mapper,ILogger<CreateGridTypeHandler> logger)
        {
            this.gridTypeRepo = gridTypeRepo;
            this.gpRepo = gpRepo;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 新建网格类型中介者处理方法
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<ApiResult<int>> Handle(CreateGridTypeCommand request, CancellationToken cancellationToken)
        {
            ApiResult<int> result = new ApiResult<int>();
            //使用分布式事务
            using (TransactionScope trans = new TransactionScope())
            {
                try
                {
                    //业务逻辑 两个添加 ,防止数据不一致,所以用了事务
                    #region  添加网格类型
                    //把请求命令的参数映射到 gridTypeModel中去
                    GridTypeModel gridTypeModel = mapper.Map<GridTypeModel>(request);
                    gridTypeModel.Id = YitIdHelper.NextId();//提前生成网格类型的id
                    int i = gridTypeRepo.CreateAsync(gridTypeModel).Result;//使用仓储把gridTypeModel添加到数据库里
                    #endregion

                    #region  添加网格类型和专业网格映射数据
                    if (request.GridTypeCategory == "逻辑网格")
                    {//处理网格类型和专业网格映射表的数据,往映射表中插入数据
                        request.Prefessionals.ForEach(p =>
                        {
                            //我们要往网格类型和专业映射表中插入数据,new 一个GridTypeProfessionMappingModel gp
                            GridTypeProfessionMappingModel gp = new GridTypeProfessionMappingModel();
                            gp.Id = YitIdHelper.NextId();//给gp对象的id赋值
                            gp.GridTypeId = gridTypeModel.Id;//给gp对象的网格类型id赋值
                            gp.ProfessionId = p; //给gp对象的专业id赋值

                            int count = gpRepo.CreateAsync(gp).Result;

                        });

                    }
                    #endregion
                    trans.Complete();//事务提交

                    //添加成功,给result返回值的内容赋值
                    result.Code = EnumResultCode.Success;
                    result.Msg = "新建网格类型成功";
                    result.Data = i;
                }
                catch (Exception e)
                {
                    //如果失败了,自动回滚
                    logger.LogError("添加网格类型和专业网格映射时发生异常:"+e.Message);//记录异常日志
                    //失败了,result赋值为失败相关信息
                    result.Code = EnumResultCode.Fail;
                    result.Msg = "新建网格类型失败";
                    result.Data = 0;
                }
            }

           return Task.FromResult(result);  //把ApiResult的对象返回给前端
        }
    }
}
